昨天的 D03: 第一支 Qt 程式裡,我們從頭建立了一個空白視窗。接著我們來給空白視窗加點東西。
昨天我們提到了 QWidget 是 Qt 裡面最基本的視窗元件單位。所有的視窗元件都是 QWidget 的子類別。這些 QWidget 是可以建立階層關係的,一個大 QWidget 底下可以擁有數個小 QWidget。小 QWidget 下面又可以有更多更小的 QWidget,層層嵌套下去。
讓我們看一眼官方的排版範例 (出自 Qt Creator 的官方範例集: Basic Layout Example)
最外圈的紅框,就是最頂層的 QWidget 視窗。紅框裡面有籃框,是紅色大視窗底下的小視窗元件,而橙框又是藍色視窗元件下面的小小視窗元件。
所有的這些色框都是 QWidget 的延伸類別。QWidget 之間互相嵌套,排出了複雜的外觀。
那我們要怎麼安排大 QWidget 底下的那些小 QWidget 的位置呢? 這就是今天的主題: Qt 的排版系統 (layout)。
請看以下程式範例。
今天的範例一樣是由一個 Qt 專案檔 (.pro
) + 一個 CPP 組成。不知道怎麼設定跟編譯 Qt 程式的人,請參考昨天的文章。
這是 Qt 專案檔,檔名 qt-layout.pro
:
QT += widgets # 引入 Qt widgets 模組
TEMPLATE = app # 這是一支應用程式 (app)
TARGET = QtLayout # 指定執行檔名字
SOURCES = qt-layout.cpp # 這支專案有一個 CPP
這是 CPP 檔,檔名 qt-layout.cpp
// 這是 qt-layout.cpp
// 注意! 引入兩個新的標頭檔
#include <QApplication>
#include <QWidget>
#include <QHBoxLayout> // 新標頭檔
#include <QPushButton> // 新標頭檔
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout* hLayout = new QHBoxLayout; // 建立排版元件!
w.setLayout(hlayout); // QWidget 指定排版元件
hlayout->addWidget(new QPushButton("紅茶"));
hlayout->addWidget(new QPushButton("綠茶"));
hlayout->addWidget(new QPushButton("烏龍茶"));
w.show();
return a.exec();
}
每個 QWidget 都可以設定一個排版元件。設定的方式是呼叫 QWidget::setLayout()
函式。而選用那一種排版元件,決定了子元件的排列方式!
QHBoxLayout* hlayout = new QHBoxLayout; // 水平排版元件!
w.setLayout(hlayout);
我們這裡選用的是 QHBoxLayout
物件(Qt Horizontal Box Layout 的縮寫,意思就是水平排版)。
往這個排版元件裡面添加三個按鈕:
hlayout->addWidget(new QPushButton("紅茶"));
hlayout->addWidget(new QPushButton("綠茶"));
hlayout->addWidget(new QPushButton("烏龍茶"));
執行程式後,你就可以看到,母視窗裡面出現了三個按鈕,水平由左而右排列。
如果把排版元件改成 QVBoxLayout
物件 (Qt Vertical Box Layout 的縮寫,意思是垂直排版)
// 別忘了 #include <QVBoxLayout>
QVBoxLayout* vLayout = new QVBoxLayout; // 排版元件!
w.setLayout(vLayout);
vLayout->addWidget(new QPushButton("紅茶"));
vLayout->addWidget(new QPushButton("綠茶"));
vLayout->addWidget(new QPushButton("烏龍茶"));
那同樣三個按鈕,就變成直的。
你可以隨意拖拉視窗,改變視窗的尺寸,排版元件都會自動調整按鈕位置。
有意思的地方是QHBoxLayout
和 QVBoxLayout
之間,是可以互相嵌套的:
QVBoxLayout* vLayout = new QVBoxLayout; // 垂直排版
w.setLayout(vLayout);
QHBoxLayout* hLayout1 = new QHBoxLayout; // 水平排版一號
hLayout1->addWidget(new QPushButton("紅茶"));
hLayout1->addWidget(new QPushButton("綠茶"));
hLayout1->addWidget(new QPushButton("烏龍茶"));
QHBoxLayout* hLayout2 = new QHBoxLayout; // 水平排版二號
hLayout2->addWidget(new QPushButton("無糖"));
hLayout2->addWidget(new QPushButton("少糖"));
hLayout2->addWidget(new QPushButton("半糖"));
// 把水平排版放進垂直排版裡
vLayout->addLayout(hLayout1);
vLayout->addLayout(hLayout2);
這段程式碼裡,QWidget 視窗下設定了垂直排版元件 vLayout
,垂直排版元件裡有兩個水平排版元件。水平排版元件裡面又各自有三個按鈕。
Qt 還提供了其他很多不同的排版元件,但是最常用、最重要的就是 QVBoxLayout
和 QHBoxLayout
這兩個基本排版。僅憑這兩個排版方式,已經可以排出不少複雜的視窗布局囉。
到目前為止,我們的視窗都只是擺著好看而已。明天,我們會接通按鈕的點擊事件,讓視窗動起來!